Hire Voip Development

Table of Content

Curious About Superior Communication?

Partner with Our Skilled Developers!

Asterisk PJSIP Configuration Guide | Endpoints, Transports, and Production Best Practices

Last updated:
October 22, 2026

Last updated:
October 22, 2026

asterisk pjsip configuration guide

📝 Blog Summary

Configuring Asterisk PJSIP means moving away from single, messy config files to a modular architecture. Instead of blending credentials, sockets, and routing together, Asterisk PJSIP configuration (res_pjsip) separates network transports, endpoint identities, contacts, and auth rules into dedicated blocks.

Because Asterisk removed legacy chan_sip in version 21, mastering PJSIP is essential for Asterisk 20 LTS, 22, and 23. This guide lays out the battle-tested configuration blueprints, covers WebRTC and ITSP trunking, and details vital security hardening.

An Asterisk PJSIP configuration sets up the network sockets, user extensions, upstream trunks, and media routing rules inside /etc/asterisk/pjsip.conf through the modular res_pjsip SIP engine.

For well over a decade, setting up an extension on Asterisk was easy: open chan_sip.conf, create [1001], set type=friend, add a password, and call it a day.

It worked, but that simplicity came with a massive architectural debt. The old channel driver handled everything (socket listening, user authentication, NAT rewriting, and media bridging) inside a single, monolithic loop. When call traffic spiked or an office dealt with registration storms, that single thread locked up, freezing active calls.

With chan_sip officially gone in Asterisk 21, PJSIP (res_pjsip) is the universal standard. It drops the monolithic approach in favor of decoupled, reusable objects.

Whether you are planning a SIP to PJSIP migration strategy or designing an enterprise communications stack from the ground up as outlined in our ultimate guide to Asterisk development, this guide will help you configure it cleanly for production.

What Is PJSIP, and Why Did Asterisk Replace chan_sip?

Asterisk PJSIP is a modern, modular SIP protocol stack written in C. Digium (now Sangoma) integrated it into Asterisk as res_pjsip to replace the fragile, single-threaded chan_sip driver with an architecture built for high concurrency and modern RFC standards.

asterisk pjsp object model

The switch from chan_sip to res_pjsip solves four major operational pain points:

  1. Independent Thread Pooling: In chan_sip, a single thread processed incoming network packets. If it choked, the whole PBX felt it. PJSIP uses a dynamic thread pool that spreads SIP parsing across all available CPU cores.
  2. Decoupled Configuration: Network interfaces, credentials, physical contact locations, and media profiles live in separate blocks. You can point a dozen different endpoints to a single network transport without repeating socket settings.
  3. Multiple Devices per Extension: With chan_sip, registering a desk phone and a mobile app to the same extension meant building hacky dialplan workarounds. PJSIP Address of Record (AOR) sections handle multi-device registration natively.
  4. Native WebRTC Integration: WebSockets (ws://, wss://), DTLS-SRTP, ICE, and dynamic STUN handling run directly in the core stack without external patches or complex third-party wrappers.

What Are the Core PJSIP Configuration Object Types and How Do They Relate?

An Asterisk PJSIP configuration inside pjsip.conf uses six core building blocks: transport, endpoint, aor, auth, identify, and registration.

Understanding how these objects snap together makes building and troubleshooting your dialplan straightforward.

pjsp relationship blueprint

1. [transport]

This sets up the network socket. It dictates the local IP, port, protocol (UDP, TCP, TLS, or WebSocket), QoS DSCP markings, and SSL/TLS certificate paths. Transports are system-level objects shared across multiple phones and trunks.

2. [endpoint]

The central profile for a phone, gateway, or trunk. It defines how a call behaves: which audio codecs are allowed, the dialplan context, NAT handling flags, DTMF signaling, and encryption rules. It does not store passwords or IP addresses directly; it references other sections:

  • transport= points to the network transport.
  • aors= points to the Address of Record object defining where the device lives.
  • auth= points to incoming authentication credentials.
  • outbound_auth= points to the credentials Asterisk sends when an upstream carrier challenges an outbound call.

3. [aor] (Address of Record)

Tells Asterisk where to send an invite for an endpoint.

  • For phones that register dynamically, it controls max_contacts (how many physical phones can register to the extension) and qualify pings.
  • For static SIP trunks, it holds the static contact= URI pointing to your provider’s IP or domain.

4. [auth]

Stores authentication credentials. It defines the username, password (or MD5 secret), and auth_type=userpass. Isolating credentials lets you share or separate auth profiles without touching endpoint routing.

5. [identify]

Maps incoming unauthenticated SIP requests to a specific endpoint based on the source IP or subnet. This is mandatory for external SIP trunks that authenticate via static IP addresses instead of username/password challenges.

6. [registration]

Tells Asterisk to register out to an external provider as a client. It stores the carrier’s outbound server URI, client credentials, and refresh intervals.

Also Read: Asterisk Development Explained for People Tired of Confusing VoIP Guides

3 Production Asterisk PJSIP Configuration Examples

The pjsip.conf file lives in /etc/asterisk/pjsip.conf. Here are three ready-to-use configurations covering internal phones, ITSP carrier trunks, and secure WebRTC browser clients.

Example 1: Basic Internal SIP Phone (Dynamic Registration)

This configuration handles a standard office phone (Extension 1001) that registers dynamically, complete with dual-device registration for a desk phone and a mobile app.

; ====================================================================
; 1. Network Transport
; ====================================================================
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060
local_net=192.168.1.0/24
local_net=10.0.0.0/16
tos=ef
cos=5

; ====================================================================
; 2. Extension 1001 Components
; ====================================================================
[1001-auth]
type=auth
auth_type=userpass
username=1001
password=SuperSecretPass4891!

[1001-aor]
type=aor
max_contacts=2              	; Desk phone AND mobile softphone
remove_existing=yes         	; Drops oldest registration if limit is reached
qualify_frequency=30        	; Keeps NAT pinhole open with OPTIONS pings

[1001]
type=endpoint
context=from-internal       	; Dialplan context in extensions.conf
transport=transport-udp
auth=1001-auth
aors=1001-aor
disallow=all
allow=ulaw
allow=alaw
allow=opus
dtmf_mode=rfc4733
direct_media=no             	; Anchor media in Asterisk for call stability
force_rport=yes             	; Respect real external source ports
rewrite_contact=yes         	; Overwrite contact headers behind NAT
rtp_symmetric=yes           	; Send media back to the packet source IP/port

Example 2: External ITSP SIP Trunk (Registration & IP Matching)

Connecting your PBX to an external telecom provider requires handling outbound registration, responding to carrier auth challenges, and matching incoming calls by IP.

; ====================================================================
; 1. Outbound Carrier Registration
; ====================================================================
[my-itsp-reg]
type=registration
outbound_auth=my-itsp-auth
server_uri=sip:sip.carrier.com
client_uri=sip:ACCOUNT_NUM@sip.carrier.com
contact_user=ACCOUNT_NUM
retry_interval=60
forbidden_retry_interval=300
expiration=3600

; ====================================================================
; 2. Carrier Credentials
; ====================================================================
[my-itsp-auth]
type=auth
auth_type=userpass
username=ACCOUNT_NUM
password=CarrierPassword987!

; ====================================================================
; 3. Static Address of Record for Outbound Calls
; ====================================================================
[my-itsp-aor]
type=aor
contact=sip:sip.carrier.com:5060
qualify_frequency=60

; ====================================================================
; 4. Trunk Endpoint Profile
; ====================================================================
[my-itsp-trunk]
type=endpoint
context=from-pstn
transport=transport-udp
disallow=all
allow=ulaw
outbound_auth=my-itsp-auth
aors=my-itsp-aor
dtmf_mode=rfc4733
direct_media=no
force_rport=yes
rewrite_contact=yes
rtp_symmetric=yes
send_rpid=yes
send_pai=yes
from_user=ACCOUNT_NUM
from_domain=sip.carrier.com

; ====================================================================
; 5. Inbound IP Matching
; ====================================================================
[my-itsp-identify]
type=identify
endpoint=my-itsp-trunk
match=198.51.100.10         	; Primary signaling IP
match=198.51.100.11         	; Secondary backup IP

Example 3: WebRTC Browser Endpoint (WSS, DTLS-SRTP & ICE)

WebRTC clients require secure WebSockets, DTLS handshake certificates, encrypted SRTP audio, and ICE candidate negotiation.

; ====================================================================
; 1. Secure WebSocket Transport
; ====================================================================
[transport-wss]
type=transport
protocol=wss
bind=0.0.0.0:8089
cert_file=/etc/asterisk/keys/asterisk.crt
priv_key_file=/etc/asterisk/keys/asterisk.key
method=tlsv1_2

; ====================================================================
; 2. WebRTC Extension 2001
; ====================================================================
[2001-auth]
type=auth
auth_type=userpass
username=2001
password=BrowserRTCSecretKey2026!

[2001-aor]
type=aor
max_contacts=1
remove_existing=yes

[2001]
type=endpoint
context=from-internal
transport=transport-wss
auth=2001-auth
aors=2001-aor
dtmf_mode=rfc4733
disallow=all
allow=opus
allow=ulaw

; WebRTC Encryption and Traversal Settings
webrtc=yes                  	; Turns on rtcp_mux, use_avpf, and bundle
dtls_auto_generate_cert=no
dtls_cert_file=/etc/asterisk/keys/asterisk.crt
dtls_private_key=/etc/asterisk/keys/asterisk.key
dtls_setup=actpass
media_encryption=dtls
ice_support=yes
direct_media=no
force_rport=yes
rewrite_contact=yes
rtp_symmetric=yes

How to Configure PJSIP for Clean NAT Traversal?

NAT issues happen because traditional SIP messages advertise private IP addresses inside their payload data. When a remote phone on another network tries to return audio, it sends voice packets to an unreachable internal subnet (like 192.168.1.50), creating silence or instant drops.

Fixing this requires configuring both the transport and the endpoint levels:

1. Transport-Level Public IP Declarations

If Asterisk runs on a cloud server behind a virtual firewall (such as AWS EC2 or an on-prem 1:1 NAT router), the transport must declare its public IP:

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0:5060
local_net=192.168.0.0/16    	; Local office LAN
local_net=10.0.0.0/8        	; Internal VPN subnet
external_media_address=203.0.113.25	; Public Elastic IP
external_signaling_address=203.0.113.25

2. The Four Vital Endpoint NAT Directives

Make sure every endpoint talking across the internet includes these four parameters:

[remote-phone]
type=endpoint
...
rtp_symmetric=yes	; Send audio back to the source IP/port the packet came from
force_rport=yes  	; Ignore Via header port; reply directly to the source port
rewrite_contact=yes  ; Overwrite Contact header with actual received public IP/port
direct_media=no  	; Anchor media in Asterisk to prevent broken peer-to-peer paths

The PJSIP Reload Trap (pjsip reload vs. core restart)

A classic trap for VoIP admins is tweaking a transport’s IP or port, typing pjsip reload, and finding that Asterisk continues running the old settings.

The underlying PJSIP C-library binds directly to operating system sockets. Tearing down and rebuilding an active network socket on a live server risks severing active media streams and crashing active worker threads.

Here is what Asterisk touches under each command:

Object type pjsip reload result Action needed to apply changes
[endpoint] Reloads immediately asterisk -rx "pjsip reload"
[aor] Reloads immediately asterisk -rx "pjsip reload"
[auth] Reloads immediately asterisk -rx "pjsip reload"
[identify] Reloads immediately asterisk -rx "pjsip reload"
[registration] Reloads immediately asterisk -rx "pjsip reload"
[transport] (standard) Ignored asterisk -rx "core restart gracefully"
[transport] (allow_reload=yes) Reloads socket asterisk -rx "pjsip reload"
[system] / [global] sections Ignored asterisk -rx "core restart now"

While you can add allow_reload=yes to a transport block, doing so on a live system will immediately drop every active call riding that socket when reloaded. Keep allow_reload=no on production boxes and schedule transport modifications during maintenance windows.

Cutting Repetition With PJSIP Templates and Wizards

Writing separate auth, aor, and endpoint blocks for hundreds of extensions leads to bloated, unmaintainable configuration files. Asterisk solves this with configuration templates and the PJSIP Configuration Wizard.

1. Native Configuration Templates

Templates let you define common phone settings once and inherit them across individual user profiles using the (!) syntax:

; ====================================================================
; Reusable Templates
; ====================================================================
[endpoint-template](!)
type=endpoint
context=from-internal
transport=transport-udp
disallow=all
allow=ulaw
allow=opus
dtmf_mode=rfc4733
direct_media=no
force_rport=yes
rewrite_contact=yes
rtp_symmetric=yes

[aor-template](!)
type=aor
max_contacts=2
remove_existing=yes
qualify_frequency=30

; ====================================================================
; Concrete Extensions
; ====================================================================
[1001-auth]
type=auth
auth_type=userpass
username=1001
password=HardenedPassword1001!

[1001-aor](aor-template)

[1001](endpoint-template)
auth=1001-auth
aors=1001-aor

2. The PJSIP Configuration Wizard (pjsip_wizard.conf)

For even leaner setups, the res_pjsip_config_wizard automatically generates the endpoint, AOR, and auth objects from a single combined block:

; In /etc/asterisk/pjsip_wizard.conf:
[user-template](!)
type=user
accepts_registrations=yes
accepts_auth=yes
endpoint/context=from-internal
endpoint/disallow=all
endpoint/allow=ulaw,opus
endpoint/dtmf_mode=rfc4733
endpoint/rtp_symmetric=yes
endpoint/force_rport=yes
endpoint/rewrite_contact=yes
aor/max_contacts=2
aor/qualify_frequency=30

[1001](user-template)
inbound_auth/username=1001
inbound_auth/password=HardenedPassword1001!

Asterisk PJSIP Production Security Hardening & Performance Best Practices

Putting a VoIP PBX on a public IP without strict PBX security controls will result in toll fraud attempts within hours. Secure your system using these proven production steps:

1. Disable Anonymous Inbound SIP

Ensure unauthenticated internet traffic cannot hit internal extension contexts. Check your pjsip.conf global settings:

[global]
type=global
default_outbound_endpoint=default_outbound_endpoint
endpoint_identifier_order=ip,username,anonymous ; Check IP and Username FIRST

Never create an [anonymous] endpoint linked to an internal or outbound dialplan context.

2. Lock Down Endpoint Identification (identify_by)

By default, Asterisk searches for endpoints using multiple methods. For internal user phones, restrict identification strictly to username:

[1001]
type=endpoint
...
identify_by=username,auth_username

For IP-authenticated SIP trunks that do not use passwords, 
restrict matching exclusively to IP:

[my-itsp-trunk]
type=endpoint
...
identify_by=ip

3. Bind Endpoints with Access Control Lists (ACL)

Prevent stolen extension passwords from being used off-site by binding internal phones to your trusted corporate subnet:

[office-acl]
type=acl
permit=192.168.1.0/24
permit=203.0.113.50/32
deny=0.0.0.0/0

[1001]
type=endpoint
...
acl=office-acl

4. Deploy Fail2Ban on Asterisk Security Logs

Configure Asterisk to write security audit events to /var/log/asterisk/security.log. In /etc/asterisk/logger.conf:

[logfiles]
security => security

Pair this with a Fail2Ban filter to automatically ban IP addresses after three failed registration attempts.

💡 VoIP Expert Tip

When employees use mobile softphones, their devices frequently switch between office Wi-Fi and 5G connections.

If max_contacts=1 and remove_existing=no, Asterisk rejects the new connection attempt with a 403 Forbidden error until the old registration timer expires.

Always configure max_contacts=2 (or higher) with remove_existing=yes on dynamic user AORs to allow clean, uninterrupted network handoffs.

Troubleshooting Asterisk PJSIP (CLI Commands and Common Error Fixes)

When phones show as unavailable, or calls fail, use the Asterisk CLI to isolate the breakdown:

Useful PJSIP CLI Diagnostic Commands

# View active endpoints and their registration status
asterisk -rx "pjsip show endpoints"

# Check active IP/port bindings for registered devices
asterisk -rx "pjsip show contacts"

# Check the registration state of outbound carrier trunks
asterisk -rx "pjsip show registrations"

# Verify which IP addresses match to which trunk endpoints
asterisk -rx "pjsip show identifies"

# Turn on full packet-level SIP tracing in the console
asterisk -rx "pjsip set logger on"

# Turn off SIP tracing
asterisk -rx "pjsip set logger off"

Common Asterisk PJSIP Configuration Errors and Solutions

  • Phone Shows “Unavailable”: Run pjsip show contacts. If the contact is missing, verify the device’s network path and ensure qualify_frequency=30 is set in the [aor] section.
  • SIP 401 / 403 Forbidden: The password sent by the client does not match the secret in the [auth] section, or the endpoint’s auth= directive points to a nonexistent auth block.
  • SIP 488 Not Acceptable Here: The endpoint and Asterisk cannot agree on a common audio codec. Verify that the allow= list in your endpoint configuration contains at least one codec supported by the client.
  • One-Way Audio: The PBX or client is sending private IP addresses in SDP media packets. Add external_media_address to your transport and confirm that rtp_symmetric=yes and force_rport=yes are present on the endpoint.
  • Calls Drop at 30 Seconds: The edge firewall is closing the UDP NAT pinhole prematurely. Disable SIP ALG on your router and set qualify_frequency=25 on the phone’s AOR.
  • “No Matching Endpoint Found” on Inbound Trunk Calls: Asterisk cannot match the incoming carrier call. Ensure you have an [identify] section matching the carrier’s exact signaling IP addresses to the trunk endpoint.

In a clean lab on your local subnet, almost any SIP stack looks solid. The wheels come off when your Asterisk box meets the public internet: hundreds of remote softphones switching from office Wi-Fi to 5G, NAT routers silently dropping UDP states at the 30-second mark, and malicious botnets hammering port 5060 with register floods.

The difference between a PBX that locks up on Monday morning and one that handles thousands of concurrent calls without a hiccup isn’t luck. It comes down to getting the mechanics right:

  • Decoupling endpoints from monolithic bindings
  • Anchoring media to bypass bad NAT paths
  • Tuning OS-level worker threadpools so audio never queues behind signaling

If you’re running Asterisk at scale, moving off legacy chan_sip, or engineering custom WebRTC pipelines, you don’t have to troubleshoot packet dumps and thread deadlocks in the dark.

At Hire VoIP Developer, we build, harden, and rescue carrier-grade VoIP infrastructure for companies that can’t afford dropped calls.

Bring in a senior Asterisk developer to audit, stabilize, or scale your switch!

FAQs

What is PJSIP, and why did Asterisk replace chan_sip with it?

PJSIP is an open-source, modular SIP protocol stack written in C. Asterisk replaced chan_sip with res_pjsip because the older driver used a single-threaded architecture that suffered from lock contention, had poor NAT handling, and could not natively support multiple devices per extension. Legacy chan_sip was completely removed in Asterisk 21.

Where is the pjsip.conf file located?

The pjsip.conf configuration file is located in /etc/asterisk/pjsip.conf on standard Linux installations. If you build Asterisk from source using custom directories, it lives in /usr/local/etc/asterisk/pjsip.conf or your custom configuration path.

What does "pjsip reload" actually reload, and why don't transport changes apply?

The command asterisk -rx "pjsip reload" updates endpoints, AORs, auth blocks, and IP identification records on the fly without dropping calls. It ignores transport changes because PJSIP binds transports directly to operating system sockets. Updating a transport requires setting allow_reload=yes or performing a core restart gracefully.

How do you configure a basic PJSIP endpoint and extension?

A working extension requires linking three sections in pjsip.conf: an [auth] section containing the username and password, an [aor] section with max_contacts controlling registration limits, and an [endpoint] section that ties them together with codecs, contexts, and transport rules.

How do I configure a PJSIP SIP trunk to an ITSP?

A reliable ITSP trunk requires five objects: a [registration] block to register Asterisk with your provider, an [auth] block for outbound credentials, an [aor] block with a static contact= URI pointing to the carrier server, an [endpoint] block setting up codecs and contexts, and an [identify] block mapping the carrier's incoming signaling IP addresses to the trunk.

Tags
Picture of Krunal Patel
Krunal Patel
Krunal Patel has a knack for turning complex technologies into practical solutions, backed by 18 years of expertise in VoIP, Asterisk, OpenSIPS, FreeSWITCH, and telecom billing. When he’s not at work, you’ll find Krunal exploring the latest gadgets, embracing his passion for all things tech.
Scroll to Top